/* package declarations and import statements */

package dbms.parse;

import java_cup.runtime.*;

%%

/* options and declarations */

%class Lexer
%unicode
%cup
%cupdebug
%line
%column
%char
%ignorecase

%{
	StringBuffer str = new StringBuffer();
	private void err(String s) {
		err(yychar, s);
	}

	private void err(int pos, String msg) {
		System.out.println("Error:" + msg + ", at position " + pos);
	}

	private Symbol symbol(int type, Object value) {
		return new Symbol(type, yyline+1, yycolumn+1, value);
	}

	private Symbol symbol(int type) {
		return new Symbol(type, yyline+1, yycolumn+1);
	}

%}

/* definitions of KEY WORDS */

LineTerminator = \n|\r|\n\r|\r\n
WhiteSpace = \n|\r|\n\r|\r\n|\t|\f
//InputCharacter = [^\r\n]

Identifier = [a-zA-Z][:jletterdigit:]*
DecIntegerLiteral = [0-9]+("."[0-9]+)?

%eofval{
	if (yystate() == STRING)
		err("ERROR: Uncompleted string at the end of the file");
	return symbol(sym.EOF, null);
%eofval}

%state STRING

%%

/* lexical rules and actions */

/* keywords */

<YYINITIAL> {
	\' { str.setLength(0); yybegin(STRING); }
	"INTEGER" { return symbol(sym.INTEGER, null); }
	"ID" { return symbol(sym.ID, null); }
	"STR" { return symbol(sym.STR, null); }
	";" { return symbol(sym.SEMICOLON, null); }
	"SELECT" { return symbol(sym.SELECT, null); }
	"select" { return symbol(sym.SELECT, null); }
	"FROM" { return symbol(sym.FROM, null); }
	"from" { return symbol(sym.FROM, null); }
	"WHERE" { return symbol(sym.WHERE, null); }
	"where" { return symbol(sym.WHERE, null); }
	"," { return symbol(sym.COMMA, null); }
	"AS" { return symbol(sym.AS, null); }
	"as" { return symbol(sym.AS, null); }
	"AND" { return symbol(sym.AND, null); }
	"and" { return symbol(sym.AND, null); }
	"CHAR" { return symbol(sym.CHAR, null); }
	"char" { return symbol(sym.CHAR, null); }
	"VARCHAR" { return symbol(sym.VARCHAR); }
	"varchar" { return symbol(sym.VARCHAR); }
	"DOUBLE" { return symbol(sym.DOUBLE); }
	"FLOAT" { return symbol(sym.FLOAT); }
	"decimal" { return symbol(sym.DECIMAL); }
	"OR" { return symbol(sym.OR, null); }
	"or" { return symbol(sym.OR, null); }
	"NOT" { return symbol(sym.NOT, null); }
	"not" { return symbol(sym.NOT, null); }
	"(" { return symbol(sym.LPAREN, null); }
	")" { return symbol(sym.RPAREN, null); }
	"=" { return symbol(sym.EQ, null); }
	"<>" { return symbol(sym.NEQ, null); }
	"<" { return symbol(sym.LT, null); }
	"<=" { return symbol(sym.LTE, null); }
	">" { return symbol(sym.GT, null); }
	">=" { return symbol(sym.GTE, null); }
	"INSERT" { return symbol(sym.INSERT, null); }
	"insert" { return symbol(sym.INSERT, null); }
	"INTO" { return symbol(sym.INTO, null); }
	"into" { return symbol(sym.INTO, null); }
	"VALUES" { return symbol(sym.VALUES, null); }
	"values" { return symbol(sym.VALUES, null); }
	"DELETE" { return symbol(sym.DELETE, null); }
	"delete" { return symbol(sym.DELETE, null); }
	"UPDATE" { return symbol(sym.UPDATE, null); }
	"update" { return symbol(sym.UPDATE, null); }
	"SET" { return symbol(sym.SET, null); }
	"set" { return symbol(sym.SET, null); }
	"CREATE" { return symbol(sym.CREATE, null); }
	"create" { return symbol(sym.CREATE, null); }
	"TABLE" { return symbol(sym.TABLE, null); }
	"table" { return symbol(sym.TABLE, null); }
	"ALTER" { return symbol(sym.ALTER, null); }
	"alter" { return symbol(sym.ALTER, null); }
	"DROP" { return symbol(sym.DROP, null); }
	"drop" { return symbol(sym.DROP, null); }
	"ADD" { return symbol(sym.ADD, null); }
	"add" { return symbol(sym.ADD, null); }
	"DEFAULT" { return symbol(sym.DEFAULT, null); }
	"default" return symbol(sym.DEFAULT, null); }
	"VIEW" { return symbol(sym.VIEW, null); }
	"view" { return symbol(sym.VIEW, null); }
	"ORDER" { return symbol(sym.ORDER, null); }
	"order" { return symbol(sym.ORDER, null); }
	"BY" { return symbol(sym.BY, null); }
	"by" { return symbol(sym.BY, null); }
	"ASC" { return symbol(sym.ASC, null); }
	"DESC" { return symbol(sym.DESC, null); }
	"PRIMARY" { return symbol(sym.PRIMARY, null); }
	"KEY" { return symbol(sym.KEY, null); }
	"FOREIGN" { return symbol(sym.FOREIGN, null); }
	"CHECK" { return symbol(sym.CHECK, null); }
	"INT" { return symbol(sym.INT, null); }
	"int" { return symbol(sym.INT, null); }
	"*" { return symbol(sym.TIMES, null); }
	"BETWEEN" { return symbol(sym.BETWEEN, null); }
	"IN" { return symbol(sym.IN, null); }
	"[" { return symbol(sym.LBRACK, null); }
	"]" { return symbol(sym.RBRACK, null); }
	"DISTINCT" { return symbol(sym.DISTINCT, null); }
	"TOP" { return symbol(sym.TOP, null); }
	"PERCENT" { return symbol(sym.PERCENT, null); }
	"INNER" { return symbol(sym.INNER, null); }
	"LEFT" { return symbol(sym.LEFT, null); }
	"RIGHT" { return symbol(sym.RIGHT, null); }
	"FULL" { return symbol(sym.FULL, null); }
	"JOIN" { return symbol(sym.JOIN, null); }
	"." { return symbol(sym.DOT, null); }
	"UNION" { return symbol(sym.UNION, null); }
	"ALL" { return symbol(sym.ALL, null); }
	"DATABASE" { return symbol(sym.DATABASE, null); }
	"NULL" { return symbol(sym.NULL, null); }
	"UNIQUE" { return symbol(sym.UNIQUE, null); }
	"COLUMN" { return symbol(sym.COLUMN, null); }
	"CONSTRAINT" { return symbol(sym.CONSTRAINT, null); }
	"INDEX" { return symbol(sym.INDEX, null); }
	"ON" { return symbol(sym.ON, null); }
	"TRUNCATE" { return symbol(sym.TRUNCATE, null); }
}

<YYINITIAL> {
	{Identifier} { return symbol(sym.ID, yytext()); }
	{DecIntegerLiteral} { String result = yytext(); if(result.contains(".")){return symbol(sym.DOUBLE, Float.parseFloat(result));} 
							else {return symbol(sym.INTEGER, new Integer(result));} }
 	{WhiteSpace} { /* ignored */ }
	" " { /* ignored */ }
}

<STRING> {
	{LineTerminator} { err("String presentation error!"); }
	\' { yybegin(YYINITIAL); return symbol(sym.STR, str.toString()); }
	[^\n\t\'\\]+ { str.append(yytext()); }
	\\n { str.append('\n'); }
	\\t { str.append('\t'); }
	\\r { str.append('\r'); }
	\\\' { str.append('\''); }
}
